#include "shmComm.hpp"

InitFIFO initFifo;

int main(int,char**,char**)
{
    // 1,通过pathname与projid生成key值
    key_t key=ftok(PATH_NAME,PROJ_ID);
    if(key==-1)
    {
        perror("ftok");
        exit(1);
    }
    
    std::cout<<time(nullptr)<<" | ftok success | key:"<<key<<std::endl;
    
    // 2,通过key值创建共享内存
    
    /*
     * IPC_CREAT: 共享内存不存在，创建之。共享内存存在，获取之。
     * IPC_CREAT+IPC_EXCL: 共享内存不存在，创建之。共享内存存在，获取失败。
     * FILE_MODE: 设置共享内存的起始权限 
     * */

    int shmid=shmget(key,IPC_SIZE,IPC_CREAT|IPC_EXCL|FILE_MODE);
    if(shmid==-1)
    {
        perror("shmget");
        exit(1);
    }
    
    std::cout<<time(nullptr)<<" | shmget success | shmid:"<<shmid<<std::endl;

    // sleep(10);

    // 3,将虚拟地址通过页表与共享内存建立映射
    void *shmaddr=shmat(shmid,nullptr,0);

    std::cout<<time(nullptr)<<" | shmat success | shmaddr:"<<shmaddr<<std::endl;

    // sleep(10);

    // 4,进行通信---读

    int fd=OpenFIFO(FIFO_PATH,READ);

    while(true)
    {
        Wait(fd);
        std::cout<<time(nullptr)<<" | Wait success | server fd:"<<fd<<std::endl;

        write(1,shmaddr,IPC_SIZE);
        fprintf(stdout,"\n");

        if(strcmp((char*)shmaddr,"quit")==0)
        {
            break;
        }
    }

    CloseFIFO(fd);
    // for(;;)
    // {
    //     write(1,shmaddr,IPC_SIZE);
    //     fprintf(stdout,"\n");
    //     if(strcmp((char*)shmaddr,"quit")==0)
    //     {
    //         break;
    //     }
    //     sleep(1);
    // }

    // for(;;)
    // {
    //     printf((char*)shmaddr);
    //     sleep(1);
    //     if(strcmp((char*)shmaddr,"quit")==0)
    //     {
    //         break;
    //     }
    // }


    // 5,虚拟地址与共享内存去关联
    int ret = shmdt(shmaddr);
    if(ret==-1)
    {
        perror("shmdt");
        exit(2);
    }

    std::cout<<time(nullptr)<<" | shmdt success | ret:"<<ret<<std::endl;

    // sleep(10);

    // 6,通过shmid删除相应的共享内存
    ret = shmctl(shmid,IPC_RMID,nullptr);
    if(ret==-1)
    {
        perror("shmctl");
        exit(3);
    }

    std::cout<<time(nullptr)<<" | shmctl success | ret:"<<ret<<std::endl;

    return 0;
}
